let obj = {
    a: 1,
    b: 2,
    c: {
        n: 3
    },
    d: ['1', '2', '3']
}


// 观察者


function observer(target) {
    // if (Array.isArray(target)) {
    //     target.__proto__ =  proto  // 重写数组的原型
    //     return
    // }
    for (let key in target) {
        defineReactive(target, key, target[key])
    }
}

function defineReactive(target, key, value) {
    if (typeof value === 'object' && value !== null) {
        observer(value)
        
    }
    Object.defineProperty(target, key, {
            get() { // 取值
                return value
            },
            set(newVal) { // 设置值
                if (newVal !== value) {
                    value = newVal
                    updateView()
                }

            }
        })

}



function updateView() {
    console.log('更新视图')
}
// let value = obj.a
// 数据劫持
// Object.defineProperty(obj, 'a', {
//     get() { // 取值
//         return value
//     },
//     set(val) { // 设置值
//         value = val
//         updateView()
//     }
// })
observer(obj)
obj.c.n = 200
obj.d.push('4')
obj['a'] = 10
console.log(obj.a) //1
console.log(obj.b) //2
console.log(obj.c.n) 


// 1. 使用数据劫持函数，递归的劫持对象上的多层对象
// 2. 直接修改数组的length属性是无效的
// 3. 对象上不存在的属性无法劫持
// 4. 重写数组上的方法